package com.wfw.utils;

import com.google.gson.Gson;
import com.wfw.model.LogInfo;
import com.wfw.service.LogInfoService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

@Aspect
//@Component
@Slf4j
public class LogAspectUtil {
    @Autowired
    private LogInfoService logInfoService;

    @Autowired
    HttpServletRequest request;

    @Pointcut("execution(public * com.wfw.*controller.*.*(..))")
    public void logPointCut(){}

    /**
     * 环绕通知 @Around  ， 当然也可以使用 @Before (前置通知)  @After (后置通知)
     * @param point
     * @return
     * @throws Throwable
     */
    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long beginTime = System.currentTimeMillis();
        Object result = point.proceed();
        long time = System.currentTimeMillis() - beginTime;
        try {
            MethodSignature signature = (MethodSignature) point.getSignature();
            Method method = signature.getMethod();
            LogInfo logInfo = new LogInfo();
            logInfo.setExecuteTime(time);
            logInfo.setLogReturn(new Gson().toJson(result));
            logInfo.setUrl(request.getRequestURL().toString());
            logInfo.setUri(request.getRequestURI());
            logInfo.setRequestIp(IPUtil.getIp(request));
            logInfo.setId(KeyUtil.genUniqueKey());


            //请求的 类名、方法名
            String className = point.getTarget().getClass().getName();
            String methodName = signature.getName();
            logInfo.setClassName(className);
            logInfo.setMethodName(methodName);
            //请求的参数
            Object[] args = point.getArgs();
            try{
                List<String> list = new ArrayList<String>();
                for (Object o : args) {
                    list.add(new Gson().toJson(o));
                }
                logInfo.setLogParam(list.toString());
            }catch (Exception e){
                log.error("保存日志异常",e);
            }
            logInfoService.insertLog(logInfo);
        } catch (Exception e) {
            log.error("处理日志切点异常",e);
        }
        return result;
    }


}
